home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Online / Qpopper / pop_send.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-31  |  4.6 KB  |  159 lines

  1. /*
  2.  * Copyright (c) 1989 Regents of the University of California.
  3.  * All rights reserved.  The Berkeley software License Agreement
  4.  * specifies the terms and conditions for redistribution.
  5.  */
  6.  
  7. #ifndef lint
  8. static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
  9. static char SccsId[] = "@(#)@(#)pop_send.c    2.1  2.1 3/18/91";
  10. #endif not lint
  11.  
  12. #include <stdio.h>
  13. #include <sys/types.h>
  14. #if defined(SOLARIS2) || defined(SYSV) || defined(AIX)
  15. #include <string.h>
  16. #define bcopy(src,dest,len)    (void) (memcpy(dest,src,len))
  17. #define bzero(dest,len)      (void) (memset(dest, (char)NULL, len))
  18. #define bcmp(b1,b2,n)        (void) (memcmp(b1,b2,n))
  19. #ifndef index
  20. # define index(s,c)        strchr(s,c)
  21. #endif
  22. #ifndef rindex
  23. # define rindex(s,c)        strrchr(s,c)
  24. #endif
  25. #else
  26. #include <strings.h>
  27. #endif
  28. #include "popper.h"
  29.  
  30. /* 
  31.  *  send:   Send the header and a specified number of lines 
  32.  *          from a mail message to a POP client.
  33.  */
  34.  
  35. pop_send(p)
  36. POP     *   p;
  37. {
  38.     MsgInfoList         *   mp;         /*  Pointer to message info list */
  39.     register int            msg_num;
  40.     register int            msg_lines;
  41.     register int        uidl_sent = 0;
  42.     char                    buffer[MAXMSGLINELEN];
  43.  
  44.     /*  Convert the first parameter into an integer */
  45.     msg_num = atoi(p->pop_parm[1]);
  46.  
  47.     /*  Is requested message out of range? */
  48.     if ((msg_num < 1) || (msg_num > p->msg_count))
  49.         return (pop_msg (p,POP_FAILURE,"Message %d does not exist.",msg_num));
  50.  
  51.     /*  Get a pointer to the message in the message list */
  52.     mp = &p->mlp[msg_num-1];
  53.  
  54.     /*  Is the message flagged for deletion? */
  55.     if (mp->del_flag)
  56.         return (pop_msg (p,POP_FAILURE,
  57.             "Message %d has been deleted.",msg_num));
  58.  
  59.     /*  If this is a TOP command, get the number of lines to send */
  60.     if (strcmp(p->pop_command,"top") == 0) {
  61.         /*  Convert the second parameter into an integer */
  62.         msg_lines = atoi(p->pop_parm[2]) + 1;
  63.     msg_lines = msg_lines > mp->body_lines ? mp->body_lines : msg_lines; 
  64.     }
  65.     else {
  66.     /* NO_STATUS does not dirty the mailspool if a status is changed */
  67. #ifndef NO_STATUS
  68.         /*  Assume that a RETR (retrieve) command was issued */
  69.     if (mp->retr_flag != TRUE)
  70.         p->dirty = 1;
  71. #endif
  72.  
  73.         msg_lines = mp->body_lines;
  74.         /*  Flag the message as retreived */
  75.         mp->retr_flag = TRUE;
  76.     }
  77.     
  78.     /*  Display the number of bytes in the message */
  79.     pop_msg(p,POP_SUCCESS,"%u octets",mp->length);
  80.  
  81.     /*  Position to the start of the message */
  82.     (void)fseek(p->drop, mp->offset, 0);
  83.  
  84.     /*  Skip the first line (the sendmail "From" or MMDF line) */
  85.     (void)fgets (buffer,MAXMSGLINELEN,p->drop);
  86.  
  87.     /*  Send the header of the message followed by a blank line */
  88.     while (fgets(buffer, MAXMSGLINELEN, p->drop)) {
  89.     if (!strncasecmp(buffer, "Content-Length:", 15) ||
  90.         !strncasecmp(buffer, "X-UIDL:", 7)) {    /* Skip UIDLs */
  91.         continue;    /* Content-Length is MTA dependent, don't send to MUA */
  92.     }
  93.  
  94.     if (!uidl_sent && (*buffer=='\n' || !strncasecmp(buffer,"Status:",7))) {
  95.         char uidl_buf[MAXMSGLINELEN];
  96.  
  97.         sprintf(uidl_buf, "%s %s", "X-UIDL:", mp->uidl_str);
  98.         pop_sendline(p, uidl_buf);
  99.         uidl_sent++;
  100.     }
  101.  
  102.     pop_sendline(p, buffer);
  103.  
  104.         /*  A single newline (blank line) signals the end of the header.
  105.         pop_sendline turns \n into \0 */
  106.  
  107.     if (*buffer == '\0')
  108.         break;
  109.  
  110.     if (hangup)
  111.           return(pop_msg(p, POP_FAILURE, "SIGHUP or SIGPIPE flagged"));
  112.     }
  113.  
  114.     /*  Send the message body */
  115.     while(fgets(buffer, MAXMSGLINELEN, p->drop)) {
  116.  
  117.         /*  Decrement the lines sent (for a TOP command) */
  118.         if (--msg_lines <= 0) break;
  119.  
  120.         pop_sendline(p,buffer);
  121.  
  122.     if (hangup)
  123.           return(pop_msg(p, POP_FAILURE, "SIGHUP or SIGPIPE flagged"));
  124.     }
  125.  
  126.     /*  "." signals the end of a multi-line transmission */
  127.     /*  Must be an fputs because pop_sendline inserts an additional . */
  128.     (void)fputs(".\r\n", p->output);
  129.     (void)fflush(p->output);
  130.  
  131.     return(POP_SUCCESS);
  132. }
  133.  
  134. /*
  135.  *  sendline:   Send a line of a multi-line response to a client.
  136.  */
  137. pop_sendline(p,buffer)
  138. POP         *   p;
  139. char        *   buffer;
  140. {
  141.     char        *   bp;
  142.  
  143.     /*  Byte stuff lines that begin with the temirnation octet */
  144.     if (*buffer == POP_TERMINATE) (void)fputc(POP_TERMINATE,p->output);
  145.  
  146.     /*  Look for a <NL> in the buffer */
  147.     if (bp = index(buffer,NEWLINE)) *bp = 0;
  148.  
  149.     /*  Send the line to the client */
  150.     (void)fputs(buffer,p->output);
  151.  
  152. #ifdef DEBUG
  153.     if(p->debug)pop_log(p,POP_DEBUG,"Sending line \"%s\"",buffer);
  154. #endif
  155.  
  156.     /*  Put a <CR><NL> if a newline was removed from the buffer */
  157.     if (bp) (void)fputs ("\r\n",p->output);
  158. }
  159.